/**
 * This class provide methods for creating data message 
 * which is to be communicated between client and server.
 * 
 * @author pkulkar@ncsu.edu
 */
package com.android.networking.message;
import java.io.Serializable;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;

import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;


public class DataMessage implements Serializable{
	DataPacket localPack;
	
	public DataPacket getLocalPack(){
		return localPack;
	}
	
	public DataMessage(int sourceSeqNumber,int pointsPathLen, 
			ArrayList pointPath,String answer,ArrayList hint,String word,long time,
			int hintCount,String extraData){
		try{
		    localPack = new DataPacket();
		    localPack.setSourceSeqNumber(sourceSeqNumber);
		    localPack.setPointsPathLen(pointsPathLen);
		    localPack.setPointPath(pointPath);
		    localPack.setAnswer(answer);
		    localPack.setWord(word);
		    localPack.setGuessTime(time);
		    localPack.setHintCount(hintCount);
		    localPack.setHint(hint);
		    localPack.setExtraData(extraData);
		}catch(Exception ex){
			ex.printStackTrace();
		}
		
	}
	public void sendCoordinates(){
		try{
			localPack.setRequestType(DataRquestType.COORDINATES);
			localPack.computeChecksum();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public void sendAnswer(){
		try{
			localPack.setRequestType(DataRquestType.ANSWER);
			localPack.computeChecksum();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public void sendHint(){
		try{
			localPack.setRequestType(DataRquestType.HINT);
			localPack.computeChecksum();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public void setRequestType(int val){
		try{
			localPack.setRequestType(val);
			localPack.computeChecksum();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public void displayControlMessage(){
		localPack.displayControlPacket();
	}
	public String toString(){
		StringBuffer buf = new StringBuffer();
		buf.append("messageType DataMessage ");
		buf.append("requestType ");
		buf.append(localPack.getRequestType());
		buf.append(" sourceSeqNumber ");
		buf.append(localPack.getSourceSeqNumber());
		buf.append(" pointsPathLen ");
		buf.append(localPack.getPointsPathLen());
		buf.append(" pointPath ");
		if(localPack.getPointsPathLen()!=0){
			buf.append(" [ ");
			ArrayList<MotionEvent> events = localPack.getPointPath();
			for(int i=0;i<events.size();i++){
				MotionEvent event = events.get(i);
				if(event.getAction() == MotionEvent.ACTION_DOWN){
					buf.append("ACTION_DOWN");
	        	}else if(event.getAction() == MotionEvent.ACTION_MOVE){
	        		buf.append("ACTION_MOVE");
	        	}else if(event.getAction() == MotionEvent.ACTION_UP){
	        		buf.append("ACTION_UP");
	        	}
				buf.append(",");
				buf.append(event.getX());
				buf.append(",");
				buf.append(event.getY());
				buf.append(";");
				Log.d("App",buf.toString());
			}
			buf.append(" ] ");
		}
		else
			buf.append(" ] ");
		buf.append(" answer ");
		buf.append(localPack.getAnswer());
		ArrayList h = localPack.getHint();
		if(h.size()!=0){
			buf.append(" hint ");
			buf.append("{");
			for(int i=0;i<h.size();i++){
				buf.append(h.get(i));
				if(i!=h.size()-1)
					buf.append(",");
			}
			buf.append("}");
		}
		buf.append(" word ");
		buf.append(localPack.getWord());
		buf.append(" guessTime ");
		buf.append(localPack.getGuessTime());
		buf.append(" hintCount ");
		buf.append(localPack.getHintCount());
		buf.append(" extraData ");
		buf.append(localPack.getExtraData());

		return buf.toString();
	}
	
	/*public static DataMessage getDataMessageInstance(String str){
		StringTokenizer tok = new StringTokenizer(str);
		String answer = null ,extraData=null,word = null;
		int requestType=-1, sourceSeqNumber=-1,pointsPathLen = -1,hintCount =-1;
		long guessTime = -1;
		ArrayList pointPath=null,hint=null;
		Log.d("App","In getDataMessageInstance");
		while(tok.hasMoreTokens()){
			String name = tok.nextToken();
			 if(name.equals("requestType"))
				 requestType = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("sourceSeqNumber"))
				 sourceSeqNumber = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("pointsPathLen"))
				 pointsPathLen = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("pointPath")){
				 name = tok.nextToken();
				 if(name.equals("[")){
					  pointPath = new ArrayList<Path>();
					 Path p = null;
					 do{
						 name = tok.nextToken(",").substring(1);
						 if(name.trim().charAt(0) != ']'){
							 float x = Float.parseFloat(tok.nextToken(","));
							 String temp = tok.nextToken(";").substring(1);
							 float y = Float.parseFloat(temp);
							 Log.d("App",x+"   "+y);
							 p = new Path();
							 if(name.equals("ACTION_DOWN")){
								 p.moveTo(x, y);
				            	 p.lineTo(x, y);
					         }else if(name.equals("ACTION_MOVE")){
								 p.lineTo(x, y);				        		
					         }else if(name.equals("ACTION_UP")){
					        	 p.lineTo(x, y);
					        }
							pointPath.add(p);
						 }else{
							 name = "]";
						 }
					 }while(!name.equals("]"));
				 }
			 }
			 else if(name.equals("answer"))
				 answer = tok.nextToken();
			 else if(name.equals("word"))
			 	word = tok.nextToken();
			 else if(name.equals("hintCount"))
				 hintCount = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("guessTime"))
				 guessTime = (Long.parseLong(tok.nextToken()));
			 else if(name.equals("hint")){
				 	name = tok.nextToken();
				 	if(name.equals("{")){
				 	hint = new ArrayList();
				 		do{
				 			name = tok.nextToken(",");
				 			hint.add(name);
				 		}while(!name.equals("}"));
				 	}
			 }
			 else if(name.equals("extraData"))
				 if(tok.hasMoreTokens())
					 extraData = tok.nextToken();
			 else{
				 tok.nextElement();
			 }
		}
		DataMessage obj = new DataMessage( 0, pointsPathLen, 
				 pointPath, answer, hint, "",1029,
				 0, extraData);
		obj.setRequestType(requestType);
		return obj;
	}*/
	
	public static DataMessage getDataMessageInstance(String str){
		StringTokenizer tok = new StringTokenizer(str);
		String answer = null ,extraData=null,word = null;
		int requestType=-1, sourceSeqNumber=-1,pointsPathLen = -1,hintCount =-1;
		long guessTime = -1;
		String name = "";
		ArrayList pointPath=null,hint=null;
		Log.d("App","In getDataMessageInstance");
		if(tok!=null)
		while(tok.hasMoreTokens()){
			try{
			name = tok.nextToken();
			 if(name.equals("requestType"))
				 requestType = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("sourceSeqNumber"))
				 sourceSeqNumber = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("pointsPathLen"))
				 pointsPathLen = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("pointPath")){
				 name = tok.nextToken();
				 if(name.equals("[")){
					  pointPath = new ArrayList<Object>();
					 Path p = null;
					// do{
						 name = tok.nextToken(",").substring(1);
						// if(name!=null)
						// {
							 if(name.trim().charAt(0) != ']'){
								 float x = Float.parseFloat(tok.nextToken(","));
								 String temp = tok.nextToken(";").substring(1);
								 float y = Float.parseFloat(temp);
								 Log.d("App",x+"   "+y);
								 /*p = new Path();
								 if(name.equals("ACTION_DOWN")){
									 p.moveTo(x, y);
					            	 p.lineTo(x, y);
						         }else if(name.equals("ACTION_MOVE")){
									 p.lineTo(x, y);				        		
						         }else if(name.equals("ACTION_UP")){
						        	 p.lineTo(x, y);
						        }
								pointPath.add(p);*/
								pointPath.add(name);
								pointPath.add(x);
								pointPath.add(y);
							 }else{
								 name = "]";
							 }
						// }
					// }while(!name.equals("]"));
				 }
			 }
			 else if(name.equals("answer"))
				 answer = tok.nextToken();
			 else if(name.equals("word"))
			 	word = tok.nextToken();
			 else if(name.equals("hintCount"))
				 hintCount = (Integer.parseInt(tok.nextToken()));
			 else if(name.equals("guessTime"))
				 guessTime = (Long.parseLong(tok.nextToken()));
			 else if(name.equals("hint")){
				 	name = tok.nextToken();
				 	if(name.equals("{")){
				 	hint = new ArrayList();
				 		do{
				 			name = tok.nextToken(",");
				 			hint.add(name);
				 		}while(!name.equals("}"));
				 	}
			 }
			 else if(name.equals("extraData"))
				 if(tok.hasMoreTokens())
					 extraData = tok.nextToken();
			 else{
				 tok.nextElement();
			 }
			}catch(Exception ex){
				Log.d("App",ex.getMessage());
				Log.d("App",str);
				return null;
			}
		}
		DataMessage obj = new DataMessage( 0, pointsPathLen, 
				 pointPath, answer, hint, "",1029,
				 0, extraData);
		obj.setRequestType(requestType);
		return obj;
	}
}
